using System.Collections.Generic;
using Microsoft.Practices.CompositeWeb;
using Microsoft.Practices.CompositeWeb.Web;
using PageFlowQuickstart.Modules.Customers.BusinessEntities;
using PageFlowQuickstart.Modules.Customers.Constants;
using PageFlowQuickstart.Infrastructure.PageFlow;
using WCSFContrib.PageFlow;
using PageFlowQuickstart.CustomersPageFlows;
using WCSFContrib.PageFlow.Xml;

namespace PageFlowQuickstart.Modules.Customers
{
    public class CustomersController
    {
        public StateValue<List<Customer>> _customers;
        private IPageFlow _customerPageFlow;

        // <snippet id="PageFlowProvider">
        private IPageFlowProvider _pageFlowProvider;

        public CustomersController([ProviderDependency(typeof(PageFlowDirectory))] XmlPageFlowProvider pageFlowProvider)
        {
            _pageFlowProvider = pageFlowProvider;
        }
        // </snippet>

        public CustomersController(IPageFlowProvider pageFlowProvider)
        {
            _pageFlowProvider = pageFlowProvider;
        }

        // <snippet id="CurrentCustomer">
        public virtual Customer CurrentCustomer
        {
            get
            {
                if (CustomersApprovalPageFlow.UserData.Contains("Customer"))
                {
                    return CustomersApprovalPageFlow.UserData["Customer"] as Customer;
                }
                return null;
            }
            private set
            {
                CustomersApprovalPageFlow.UserData["Customer"] = value;
            }
        }
        // </snippet>

        // <snippet id="CustomersApprovalPageFlow">
        protected IPageFlow CustomersApprovalPageFlow
        {
            get
            {
                if (_customerPageFlow == null)
                {
                    _customerPageFlow = _pageFlowProvider.GetPageFlow(typeof(CustomersApprovalXmlPageFlow));
                }
                return _customerPageFlow;
            }
        }
        // </snippet>

        // <snippet id="StartcustomerApproval">
        public virtual void StartCustomerApproval()
        {
            if (CustomersApprovalPageFlow.Status != PageFlowStatus.Running)
            {
                CustomersApprovalPageFlow.Start();
            }
            CurrentCustomer = GetNextCustomer();
            CustomersApprovalPageFlow.RedirectToCurrentPage();
        }
        // </snippet>

        // <snippet id="ApproveCurrentCustomer">
        public virtual void ApproveCurrentCustomer()
        {
            Customer current = CurrentCustomer;
            current.Approved = true;
            CurrentCustomer = current;
            UpdateCustomerInDataStore(current);
            CustomersApprovalPageFlow.Navigate("ApproveCustomer");
        }
        // </snippet>

        // <snippet id="FinishCustomerApproval">
        public virtual void FinishCustomerApproval()
        {
            CustomersApprovalPageFlow.Complete();
        }
        // </snippet>

        // Simulates an update in the data store
        private void UpdateCustomerInDataStore(Customer customer)
        {
            Customer customerFound = FindCustomer(customer);
            customerFound.Approved = customer.Approved;
            customerFound.LastName = customer.LastName;
            customerFound.Name = customer.Name;
        }

        private Customer FindCustomer(Customer customer)
        {
            return Customers.Find(delegate(Customer match)
            {
                return match.Id == customer.Id;
            });
        }

        private List<Customer> Customers
        {
            get
            {
                if (_customers.Value == null)
                {
                    // Set up a mock customers data store
                    _customers.Value = new List<Customer>();
                    _customers.Value.Add(new Customer(1000, "Enrique", "Gil", false));
                    _customers.Value.Add(new Customer(1001, "Paul", "West", false));
                    _customers.Value.Add(new Customer(1002, "Nuria", "Gonzalez", false));
                }
                return _customers.Value;
            }
        }

        private Customer GetNextCustomer()
        {
            return Customers.Find(delegate(Customer customer)
            {
                return !customer.Approved;
            });
        }
    }
}
